# -*- coding: utf-8 -*-

# TwinConf
# Feel free to add comments and pas extra stuff You would have fitted in.
# gravatasufoca@yahoo.com.br
# Bruno Teixeira canto de Lima 

from Components.ActionMap import ActionMap
from Components.config import config, ConfigText, getConfigListEntry, ConfigInteger, ConfigSelection, ConfigSubsection, ConfigYesNo
from Components.ConfigList import ConfigListScreen
from Components.Label import Label

from Plugins.Plugin import PluginDescriptor

from Screens.Screen import Screen
from Screens.Console import Console
import re
from Components.MenuList import MenuList
from Screens.MessageBox import MessageBox
from Components.Converter import CaidDisplay


twin2cc_version = "0.8.5"
twin2cc_plugindir = "/usr/lib/enigma2/python/Plugins/Extensions/TwinConf" 
twin2cc_init = "/etc/init.d/twin2cc"
twin2cc_cfg = "/etc/twin/twin2cc.cfg"
twin2cc_channelinfo = "/etc/twin/twin2cc.channelinfo"
oscam_channelinfo = "/etc/tuxbox/config/oscam-twin/oscam.twin"
twin2cc_title = "TwinConfig"
twin2cc_developer = "gravatasufoca"



# Configuration
config.plugins.Twinconf = ConfigSubsection()
config.plugins.Twinconf.serial = ConfigSelection(default="/dev/ttyUSB0", choices=[
        ("/dev/ttyUSB0", "usb0"),
        ("/dev/ttyUSB1", "usb1")
        ])
config.plugins.Twinconf.port = ConfigInteger(default=12321)
config.plugins.Twinconf.try_delay = ConfigInteger(default=1000000)
config.plugins.Twinconf.timeout = ConfigInteger(default=300000)



# Channel
config.plugins.Channel = ConfigSubsection()
config.plugins.Channel.tipo = ConfigSelection(default="twin", choices=[
        ("twin", "twin"),
        ("oscam", "oscam")
        ])

#user configuration
config.plugins.UserConf = ConfigSubsection()
config.plugins.UserConf.name = ConfigText(fixed_size=False)
config.plugins.UserConf.password = ConfigText(fixed_size=False)

#Satellite configuration
config.plugins.SatConf = ConfigSubsection()
config.plugins.SatConf.name = ConfigText(fixed_size=False)
config.plugins.SatConf.timeout = ConfigInteger(default=1000000)
config.plugins.SatConf.position = ConfigSelection(default="W", choices=[
        ("W", "W"),
        ("E", "E")
        ])
config.plugins.SatConf.caid = ConfigSelection(choices=[])
config.plugins.SatConf.pref = ConfigYesNo(default=False)


#card configuration
config.plugins.CardConf = ConfigSubsection()
config.plugins.CardConf.name = ConfigText(fixed_size=False)

# Class TwinScreen
class TwinScreen(ConfigListScreen, Screen):
    skin = """
        <screen position="600,500" size="600,200" title="%s %s">
        
        <ePixmap pixmap="skin_default/buttons/key_menu.png" position="450,164" size="50,30" transparent="1" alphatest="on" />
        
        <widget position="0,0" size="590,160" name="config" scrollbarMode="showOnDemand" transparent="1"/>
       
        <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttongreen" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="green" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttonyellow" position="220,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="yellow" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" /> 
        <widget name="buttonblue" position="325,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="blue" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        
        <widget name="buttoninfo" position="470,164" zPosition="1" size="140,30" font="Regular;18" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />

        </screen>""" % (twin2cc_title, twin2cc_version)

#        <widget position="290,164" size="80,36" valign="center" halign="center" zPosition="2" name="buttonblue" backgroundColor="blue" foregroundColor="white" font="Regular;17"/>

    def __init__(self, session):
                
        self.session = session
        Screen.__init__(self, session)
        self.list = []
        self.loadConfig() 
        self.onShow.append(self.loadConfig)
        self.list.append(getConfigListEntry("SERIAL DEVICE", config.plugins.Twinconf.serial))
        self.list.append(getConfigListEntry("LISTEN PORT", config.plugins.Twinconf.port))
        self.list.append(getConfigListEntry("TWIN_TRY_DELAY", config.plugins.Twinconf.try_delay))

        
        ConfigListScreen.__init__(self, self.list)
         
        self["buttonred"] = Label("Restart")
        self["buttongreen"] = Label("Users")
        self["buttonyellow"] = Label("Cards")
        self["buttonblue"] = Label("Satellites")
        self["buttoninfo"] = Label("ChannelInfo")
        
        self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MenuActions"],
        {
            "blue": self.showSats,
            "yellow": self.showCards,
            "green": self.showUsers,
            "red": self.restart,
            "ok": self.save,
            "cancel": self.cancel,
            "menu": self.showChannel
        }, -2)


    def cancel(self):
        for i in self["config"].list:
            i[1].cancel()
        self.close(False)

    def save(self):
        for i in self["config"].list:
            i[1].save()
        
        self.changeFile()
        self.session.open(MessageBox, _("Saved successfully!"), MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)
       
    def restart(self,answer=True):
        if answer:
            title = _("starting/restaring Twin2cc")
            cmd = "%s start" % twin2cc_init
            self.session.open(Console, _(title), ["killall twin2cc", cmd])
    
    def showChannel(self):
        self.session.open(ChannelScreenConf)
            
    def showUsers(self):
        self.session.open(TwinUsersList)
    
    def showSats(self):
        self.session.open(SatelliteList)
    
    def showCards(self):
        self.session.open(CardList)
    

    def changeFile(self):
        from tempfile import mkstemp 
        from shutil import move 
        from os import remove, close 
        
        old_file = open(twin2cc_cfg, "r+")
        
        #Create temp file 
        fh, abs_path = mkstemp() 
        new_file = open(abs_path, 'w') 
        
        for line in old_file.readlines():
            new_line = line
            
            if not new_line[0] == "#":      
                if re.match("(\s+)??(SERIAL)\s+(DEVICE)(\s+)??\:", new_line):
                    new_line = "SERIAL DEVICE: %s\n" % config.plugins.Twinconf.serial.value
                elif re.match("(\s+)??(LISTEN)\s+(PORT)(\s+)??\:", new_line):
                    new_line = "LISTEN PORT: %s\n" % config.plugins.Twinconf.port.value
                elif re.match("(\s+)??(TWIN_TRY_DELAY)(\s+)??\:", new_line):
                    new_line = "TWIN_TRY_DELAY: %s\n" % config.plugins.Twinconf.try_delay.value
                elif re.match("(\s+)??(TWIN_TIME_OUT_NRW)(\s+)??\:", new_line):
                    new_line = "TWIN_TIME_OUT: %s\n" % config.plugins.Twinconf.timeout.value
              
            new_file.write(new_line)
        
        #close temp file 
        new_file.close() 
        close(fh) 
        old_file.close() 
        #Remove original file 
        remove(twin2cc_cfg) 
        #Move new file 
        move(abs_path, twin2cc_cfg) 

    def loadConfig(self):
        
        old_file = open(twin2cc_cfg, "r")
        
        for line in old_file.readlines():
            
            if not line[0] == "#":      
                if re.match("(\s+)??(SERIAL)\s+(DEVICE)(\s+)??\:", line):
                    value = re.split(":", line)[1].strip()
                    config.plugins.Twinconf.serial.value = value
                elif re.match("(\s+)??(LISTEN)\s+(PORT)(\s+)??\:", line):
                    value = int(re.split(":", line)[1].strip(), 0)
                    config.plugins.Twinconf.port.value = value
                elif re.match("(\s+)??(TWIN_TRY_DELAY)(\s+)??\:", line):
                    value = int(re.split(":", line)[1].strip(), 0)
                    config.plugins.Twinconf.try_delay.value = value
                elif re.match("(\s+)??(TWIN_TIME_OUT_NRW)(\s+)??\:", line):
                    value = int(re.split(":", line)[1].strip(), 0)
                    config.plugins.Twinconf.timeout.value = value
              
         
        old_file.close() 
        
        

# Class ChannelScreenConf
class ChannelScreenConf(ConfigListScreen, Screen):
    skin = """
        <screen position="600,500" size="600,200" title="%s %s">                
        
        <widget position="0,0" size="590,160" name="config" scrollbarMode="showOnDemand" transparent="1"/>
       
        <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttongreen" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="green" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        
        </screen>""" % (twin2cc_title, twin2cc_version)

#        <widget position="290,164" size="80,36" valign="center" halign="center" zPosition="2" name="buttonblue" backgroundColor="blue" foregroundColor="white" font="Regular;17"/>

    def __init__(self, session):
        self.session = session
        Screen.__init__(self, session)
        self.list = []
        self.list.append(getConfigListEntry("List type", config.plugins.Channel.tipo))        
        
        ConfigListScreen.__init__(self, self.list)
         
        self["buttonred"] = Label("Cancel")
        self["buttongreen"] = Label("Generate")

        
        self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MenuActions"],
        {
            "green": self.confirma,
            "red": self.cancel,
            "ok": self.confirma,
            "cancel": self.cancel
        }, -2)

    def confirma(self):
        if config.plugins.Channel.tipo=="twin":
            self.session.openWithCallback(self.gerarChannel, MessageBox, _("Do you really want to create the channelinfo?"), MessageBox.TYPE_YESNO)
        else:
            self.session.openWithCallback(self.gerarChannelOscam, MessageBox, _("Do you really want to create the channelinfo?"), MessageBox.TYPE_YESNO)

        
    def gerarChannel(self,answer):
        
        if answer:
            from enigma import eServiceReference, eServiceCenter, iServiceInformation
            from Components.Sources.ServiceList import ServiceList        
            
    
            satList=getSatList()
    
            currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
            servicelist = ServiceList("")
            servicelist.setRoot(currentServiceRef)
            canais = servicelist.getServicesAsList()
            
            servicehandler = eServiceCenter.getInstance()
            
            canaisValidos={}
            #count=0
            for item in canais:
                canal = eServiceReference(item[0])            
                if canal:                
    #                if (canal.type==1 or canal.type==25) and servicehandler.info(canal).getName(canal)!="(...)":
                        transponder_info = servicehandler.info(canal).getInfoObject(canal, iServiceInformation.sTransponderData)
                        frequencia = hex(int(transponder_info["frequency"]) / 1000)[2:]
                        sid = canal.toString().split(":")[3]
                        position = int(transponder_info["orbital_position"])
                        if position > 1800:
                            satName= str(int(((float(position)/10)-360)*-1))
                            sat=getSat(satName=satName, satList=satList)                    
                            position = hex((360 - int(((float(position) / 10) - 360) * -1)) * 10)[2:]                   
                           
                        else:
                            satName= str(int(((float(position)/10)+180)*-1))
                            sat=getSat(satName=satName, satList=satList)  
                            position = hex((int(((float(position) / 10) + 180) * -1)) * 10)[2:]                   
                  
                        i = 4-len(str(position))
                        position=str(position)
                        position = "0%s" % position
                        i -= 1
                        
                        sid=str(sid)
                        i = 4-len(str(sid))
                        while i > 0:
                            sid = "0%s" % sid
                            i -= 1 
                            
                        nome = servicehandler.info(canal).getName(canal)
    #                    CAID=1802 : PROVIDER=000000 : SID=0153 : Pos Sat=61w => 360-61 = 299 => 2990 => 0BAE : Freq=11135 => 2B7F + uma descrição entre aspas         
                        caid=""
                        if sat:
                            caid=sat[sat.keys()[0]].get("caid")
                        #count+=1
                        
                        key="%s:000000:%s" % (caid, sid)
                        if canaisValidos.has_key(key):
                            if sat[sat.keys()[0]].get("pref"):                           
                                canaisValidos[key]="%s:000000:%s:%s:%s \"%s (%s)\"\n" % (caid, sid, position, frequencia, nome,satName)
                        else:
                            canaisValidos[key]="%s:000000:%s:%s:%s \"%s (%s)\"\n" % (caid, sid, position, frequencia, nome,satName)
            
            
            tmp = open(twin2cc_channelinfo, "w")
            tmp.write("################### TWINCONF ######################\n")     
            canais=canaisValidos.items()
            canais.sort(key=lambda x: (re.split("\"",x[1]))[1] )

            for valor in canais:
                tmp.write(valor[1])
            
            #tmp.write("%s:000000:%s:%s:%s \"%s\"\n" % (caid, sid, position, frequencia, nome))             
            tmp.close()
            
            self.session.openWithCallback(self.restart, MessageBox, _("Channelinfo created successfully!\n%d channels was created.\nRestart Twin2cc now?") % (canaisValidos.__len__()), MessageBox.TYPE_YESNO)
    
    #        self.session.open( MessageBox, _("Channelinfo created successfully!\n%d channels was created.") % (count) ,timeout=5, MessageBox.TYPE_INFO,close_on_any_key=True)
    
    
    def gerarChannelOscam(self,answer):
        #formato
        #1802:000000:2900:12160:903 # Teste 03 (70W)
        #caid:000000:sat:freq:sid # nome
        if answer:
            from enigma import eServiceReference, eServiceCenter, iServiceInformation
            from Components.Sources.ServiceList import ServiceList        
            
    
            satList=getSatList()
    
            currentServiceRef = self.session.nav.getCurrentlyPlayingServiceReference()
            servicelist = ServiceList("")
            servicelist.setRoot(currentServiceRef)
            canais = servicelist.getServicesAsList()
            
            servicehandler = eServiceCenter.getInstance()
            
            canaisValidos={}
            #count=0
            for item in canais:
                canal = eServiceReference(item[0])            
                if canal:                                  
    #                if (canal.type==1 or canal.type==25) and servicehandler.info(canal).getName(canal)!="(...)":
                        transponder_info = servicehandler.info(canal).getInfoObject(canal, iServiceInformation.sTransponderData)
                        frequencia = int(transponder_info["frequency"]) / 1000
                        sid = (canal.toString().split(":")[3])
                                             
                        position = int(transponder_info["orbital_position"])
                        
                        if position > 1800:
                            satName= str(int(((float(position)/10)-360)*-1))
                            sat=getSat(satName=satName, satList=satList)                                                            
                           
                        else:
                            satName= str(int(((float(position)/10)+180)*-1))
                            sat=getSat(satName=satName, satList=satList)  
                  
                        position=str(position)
                     
                        
                        sid=str(int(sid,16))
                                                   
                        nome = servicehandler.info(canal).getName(canal)
                        
                        caid=""
                        if sat:
                            caid=sat[sat.keys()[0]].get("caid")
                        #count+=1
                        
                        key="%s:000000:%s" % (caid, sid)
                        #caid:000000:sat:freq:sid # nome
                        if canaisValidos.has_key(key):
                            if sat[sat.keys()[0]].get("pref"):                           
                                canaisValidos[key]="%s:000000:%s:%s:%s # %s (%s)\n" % (caid, position, frequencia,sid,nome,satName)
                        else:
                            canaisValidos[key]="%s:000000:%s:%s:%s # %s (%s)\n" % (caid, position, frequencia,sid,nome,satName)
            
            
            tmp = open(oscam_channelinfo, "w")
            tmp.write("################### TWINCONF ######################\n")     
            canais=canaisValidos.items()
            canais.sort(key=lambda x: (re.split(":",x[1]))[2] ,reverse=True)

            for valor in canais:
                tmp.write(valor[1])
            
            #tmp.write("%s:000000:%s:%s:%s \"%s\"\n" % (caid, sid, position, frequencia, nome))             
            tmp.close()
            self.session.open(MessageBox,_("oscam.twin created successfully!\n%d channels was created.\nYou must restart oscam!!!") % (canaisValidos.__len__()), MessageBox.TYPE_WARNING, close_on_any_key=True, timeout=5)

   
        
    def cancel(self):
        for i in self["config"].list:
            i[1].cancel()
        self.close(False)



# Class UserScreenConf
class UserScreenConf(ConfigListScreen, Screen):
    
    skin = """
        <screen position="600,500" size="600,200"  title="User Configuration">
        <widget transparent="1" position="0,0" size="500,160" name="config" scrollbarMode="showOnDemand"/>

        <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttongreen" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="green" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 

        </screen>"""
        
    def __init__(self, session, userValue, userList):
        self.session = session
        Screen.__init__(self, session)
        
        self.list = []
        self.userList = userList
        self.user = None
        self.old_name = ""
        name = "twin"
        password = "twin"
        self.edit = False
        if userValue is not -1:
            self.edit = True
            self.user = userValue
            name = self.user[self.user.keys()[0]].get("name")
            password = self.user[self.user.keys()[0]].get("password")
            self.old_name = name
        
             
        config.plugins.UserConf.name.value = name
        config.plugins.UserConf.password.value = password
        
        self.list.append(getConfigListEntry("Name", config.plugins.UserConf.name))
        self.list.append(getConfigListEntry("Password", config.plugins.UserConf.password))
        
        ConfigListScreen.__init__(self, self.list)
        self["buttonred"] = Label("Cancel")
        self["buttongreen"] = Label("Save")
        self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
        {
            "red": self.cancel,
            "cancel": self.cancel,
            "save": self.save,
            "green": self.save,
            "ok": self.save
        }, -2)

    def cancel(self):
        for i in self["config"].list:
            i[1].cancel()
        self.close(True)
                

        
    def save(self):
        
        if len(config.plugins.UserConf.name.value) == 0 or len(config.plugins.UserConf.password.value) == 0:
            self.session.open(MessageBox, _("All fields are required!"), MessageBox.TYPE_WARNING, close_on_any_key=True, timeout=5)
        else:
            if self.checkUser(config.plugins.UserConf.name.value):
            
                for i in self["config"].list:
                    i[1].save()
                
                if self.user is not None:            
                    self.userList.remove(self.user)
                    
                user = {}
                user[config.plugins.UserConf.name.value] = {"name":config.plugins.UserConf.name.value, "password":config.plugins.UserConf.password.value}
                self.userList.append(user)
                saveUsers(self.userList)
                self.session.open(MessageBox, _("The User %s was saved successfully") % config.plugins.UserConf.name.value , MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)
                self.close()
            else:
                self.session.open(MessageBox, _("The user already exist!"), MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)

    def checkUser(self, name):        
        user = self.getUser(name)
        if user is not None:
            if self.edit and name == self.old_name:
                return True
            else:
                return False
        return True
    
    def getUser(self, userName):        
        for user in self.userList :
            if user.get(userName) is not None:
                return user 

class TwinUsersList(Screen):
        
    skin = """    
        <screen position="600,500" size="600,200" title="Twin Users List" >
         <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
          <widget name="buttonblue" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="blue" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 

            <widget transparent="1" name="menu" position="0,0" size="590,160" scrollbarMode="showOnDemand" />
        </screen>""" 
        
    def __init__(self, session, args=0):
        self.skin = TwinUsersList.skin
        self.session = session
        Screen.__init__(self, session)
        self.menuList = []
        self.getMenuItens()
        self.menu = args
        self.onShow.append(self.updateMenu)
        self["menu"] = MenuList(self.menuList, enableWrapAround=True)
        self["buttonred"] = Label("Remove")
        self["buttonblue"] = Label("Add")
        self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions"],
                                    {
                                        "ok": self.go,
                                        "cancel": self.fechar,
                                        "back": self.fechar,
                                        "red": self.erase,
                                        "blue": self.add
                                    }, -1)
        
    
    def updateMenu(self):
        self.getMenuItens()
        self["menu"].setList(self.menuList)
                          
        
    def fechar(self):
        self["menu"].setList([])
        self.close()
    
    def go(self):
        returnValue = self["menu"].l.getCurrentSelection()[1]
        if returnValue is not None:  
            user = self.getUser(returnValue)          
            self.session.open(UserScreenConf, user, self.getUserList())

    def erase(self):
        self.session.openWithCallback(self.remove, MessageBox, _("Confirm removal?"), MessageBox.TYPE_YESNO)
        
    def remove(self, answer):
        if answer == True:
            returnValue = self["menu"].l.getCurrentSelection()[1]
            if returnValue is not None:
                user = self.getUser(returnValue)
                if user is not None:
                    users = self.getUserList()
                    users.remove(user)
                    saveUsers(users)
                    self.updateMenu()                  
    
    def add(self):
        returnValue = -1
        self.session.open(UserScreenConf, returnValue, self.getUserList())
    
    def getMenuItens(self):
        menuItens = []
        for user in self.getUserList():
            name = user[user.keys()[0]].get("name")           
            menuItens.append((_(name), name))

        self.menuList = menuItens
    
    def getUserList(self):
    
#        if not len(self.userList):
        usersList = []
        
        arq = open(twin2cc_cfg, "r")
        
        #Create temp file 
        
        for line in arq.readlines():
            
            #test if is not a comment
            if not line[0] == "#":     
                #is a F: ?" 
                if re.match("(\s+)??(F)(\s+)??\:", line):
                    #split the line to get the values
                    info = re.split("\W+", line.strip())
                                
                    name = info[1]
                    password = info[2]
                    #append the new user
                    user = {}
                    user[name] = {"name":name, "password":password}
                    usersList.append(user)                    
                    
                    
        arq.close()
            
        return sorted(usersList)
        
    def getUser(self, userName):
        
        for user in self.getUserList():
            if user.get(userName) is not None:
                return user  
    



# Class SatelliteScreenConf
class SatelliteScreenConf(ConfigListScreen, Screen):
    
    skin = """
        <screen position="600,500" size="600,200"  title="Satellite Configuration">
            <widget transparent="1" position="0,0" size="590,160" name="config" scrollbarMode="showOnDemand"/>
            <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
            <widget name="buttongreen" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="green" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        </screen>"""
        
    def __init__(self, session, satValue, satList):
        self.session = session
        Screen.__init__(self, session)
        
        self.list = []
        self.satList = satList
        self.sat = None
        self.old_name = ""
        name = "00"
        timeout = 1000000
        position = "W"
        self.edit = False
        if satValue is not -1:
            self.edit = True
            self.sat = satValue
            position = self.sat[self.sat.keys()[0]].get("position")
            name = self.sat[self.sat.keys()[0]].get("name")
            timeout = self.sat[self.sat.keys()[0]].get("timeout")
            caid = self.sat[self.sat.keys()[0]].get("caid")
            pref = self.sat[self.sat.keys()[0]].get("pref")
            self.old_name = name
        
        self.carregaCaids()  
        config.plugins.SatConf.name.value = name
        config.plugins.SatConf.timeout.value = timeout
        config.plugins.SatConf.position.value = position
        config.plugins.SatConf.caid.value = caid
        config.plugins.SatConf.pref.value = pref
        
        self.list.append(getConfigListEntry("Position", config.plugins.SatConf.position))
        self.list.append(getConfigListEntry("Sat", config.plugins.SatConf.name))
        self.list.append(getConfigListEntry("Timeout", config.plugins.SatConf.timeout))
        self.list.append(getConfigListEntry("CAID", config.plugins.SatConf.caid))
        self.list.append(getConfigListEntry("Preferential", config.plugins.SatConf.pref))
        
        ConfigListScreen.__init__(self, self.list)
        self["buttonred"] = Label("Cancel")
        self["buttongreen"] = Label("Save")
        self["actions"] = ActionMap(["SetupActions", "OkCancelActions", "ColorActions", "DirectionActions"], {
            "red": self.cancel,
            "cancel": self.cancel,
            "save": self.save,
            "green": self.save,
            "ok": self.save
        }, -2)

    def cancel(self):
        for i in self["config"].list:
            i[1].cancel()
        self.close(True)
                
    def save(self):
        
        if len(config.plugins.SatConf.name.value) == 0:
            self.session.open(MessageBox, _("All fields are required!"), MessageBox.TYPE_WARNING, close_on_any_key=True, timeout=5)
        else:
            if self.checkSat(config.plugins.SatConf.name.value):
            
                for i in self["config"].list:
                    i[1].save()
                
                if self.sat is not None:            
                    self.satList.remove(self.sat)
                    
                sat = {}
                sat[config.plugins.SatConf.name.value] = {"name":config.plugins.SatConf.name.value, "timeout":config.plugins.SatConf.timeout.value, "position":config.plugins.SatConf.position.value, "caid":config.plugins.SatConf.caid.value}
                self.satList.append(sat)
                saveSats(self.satList)
                self.session.open(MessageBox, _("The Satellite %s was saved successfully") % config.plugins.SatConf.name.value , MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)
                self.close()
            else:
                self.session.open(MessageBox, _("The Satellite already exist!"), MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)

    def checkSat(self, name):        
        sat = getSat(name)
        if sat is not None:
            if self.edit and self.old_name == name:
                return True
            else:
                return False
        return True
    
        
    def carregaCaids(self):
        cardList = []
        
        arq = open(twin2cc_cfg, "r")
        
        #Create temp file 
        
        for line in arq.readlines():
            
            #test if is not a comment
            if not line[0] == "#":     
                #is a F: ?" 
                if re.match("(\s+)??(CARD)\s+", line):
                    #split the line to get the values
                    info = re.split("\W+", line.strip())
                    
                    name = info[1]
                    #append the new card
                    card = (name, name)
                    cardList.append(card)                    
                                        
        arq.close()
            
        cardList = sorted(cardList)
                 
        config.plugins.SatConf.caid.setChoices(choices=cardList)

class SatelliteList(Screen):
        
    skin = """    
        <screen position="600,500" size="600,200" title="Satellites List" >
         <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttonblue" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="blue" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 

            <widget transparent="1" name="menu" position="0,0" size="590,160" scrollbarMode="showOnDemand" />
        </screen>""" 
        
    def __init__(self, session, args=0):
        self.skin = SatelliteList.skin
        self.session = session
        Screen.__init__(self, session)
        self.menuList = []
        self.getMenuItens()
        self.menu = args
        self.onShow.append(self.updateMenu)
        self["menu"] = MenuList(self.menuList, enableWrapAround=True)
        self["buttonred"] = Label("Remove")
        self["buttonblue"] = Label("Add")
        self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions"],
                                    {
                                        "ok": self.go,
                                        "cancel": self.fechar,
                                        "back": self.fechar,
                                        "red": self.erase,
                                        "blue": self.add
                                    }, -1)
        
    
    def updateMenu(self):
        self.getMenuItens()
        self["menu"].setList(self.menuList)
                          
        
    def fechar(self):
        self["menu"].setList([])
        self.close()
    
    def go(self):
        returnValue = self["menu"].l.getCurrentSelection()[1]
        if returnValue is not None:  
            sat = getSat(returnValue)      
            self.session.open(SatelliteScreenConf, sat, getSatList())

    def erase(self):
        self.session.openWithCallback(self.remove, MessageBox, _("Confirm removal?"), MessageBox.TYPE_YESNO)
        
    def remove(self, answer):
        if answer == True:
            returnValue = self["menu"].l.getCurrentSelection()[1]
            if returnValue is not None:
                sat = getSat(returnValue)
                if sat is not None:
                    sats = getSatList()
                    sats.remove(sat)
                    saveSats(sats)
                    self.updateMenu()                  
    
    def add(self):
        returnValue = -1
        self.session.open(SatelliteScreenConf, returnValue, getSatList())
    
    def getMenuItens(self):
        menuItens = []
        for sat in getSatList():
            name = sat[sat.keys()[0]].get("name")           
            menuItens.append((_(name), name))

        self.menuList = menuItens
    
def getSatList():
    import ast

#        if not len(self.userList):
    satList = []
    
    arq = open(twin2cc_cfg, "r")
    
    #Create temp file 
    
    for line in arq.readlines():
        
        #test if is not a comment
        if not line[0] == "#":     
            #is a F: ?" 
            if re.match("(\s+)??(SAT)(\s+)??", line):
                #split the line to get the values
                info = re.split("\W+", line.strip())
                            
                position = info[3]
                
                if position=="W":
                    name = str((int(info[1], 16) / 10 - 360) * -1)
                else:
                    name = str((int(info[1], 16) / 10) * -1)
                
                timeout = int(info[2], 0)
               
                caid = info[4]
                pref = info[5]
                if type(pref).__name__=='str':
                    pref=ast.literal_eval(pref)
                #append the new sat
                sat = {}
                sat[name] = {"name":name, "timeout":timeout, "position":position,"caid":caid,"pref":pref}
                satList.append(sat)                    
                
                
    arq.close()
        
    return sorted(satList)
    
def getSat(satName="",satList=None):
    if satList is None:
        lista=getSatList() 
    else:
        lista=satList
            
    for sat in lista:
        satName= str(satName).strip()
        if sat.get(satName) is not None:
            return sat    

# Class CardScreenConf
class CardScreenConf(ConfigListScreen, Screen):
    
    skin = """
        <screen position="600,500" size="600,200"  title="Card Configuration">
        <widget transparent="1" position="0,0" size="590,160" name="config" scrollbarMode="showOnDemand"/>
         <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttongreen" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="green" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 

        </screen>"""
        
    def __init__(self, session, cardValue, cardList):
        self.session = session
        Screen.__init__(self, session)
        
        self.list = []
        self.cardList = cardList
        self.card = None
        self.old_card = ""
        name = "0000"
        self.edit = False
        if cardValue is not -1:
            self.edit = True
            self.card = cardValue
            name = self.card[self.card.keys()[0]].get("name")
            self.old_card = name
             
        config.plugins.CardConf.name.value = name
        
        self.list.append(getConfigListEntry("CAID", config.plugins.CardConf.name))
        
        ConfigListScreen.__init__(self, self.list)
        self["buttonred"] = Label("Cancel")
        self["buttongreen"] = Label("Save")
        self["actions"] = ActionMap(["SetupActions", "OkCancelActions", "ColorActions", "DirectionActions"], {
            "red": self.cancel,
            "cancel": self.cancel,
            "save": self.save,
            "green": self.save,
            "ok": self.save
        }, -2)

    def cancel(self):
        for i in self["config"].list:
            i[1].cancel()
        self.close(True)
                
    def save(self):
        
        if len(config.plugins.CardConf.name.value) == 0:
            self.session.open(MessageBox, _("All fields are required!"), MessageBox.TYPE_WARNING, close_on_any_key=True, timeout=5)
        else:
            if self.checkCard(config.plugins.CardConf.name.value):
            
                for i in self["config"].list:
                    i[1].save()
                
                if self.card is not None:            
                    self.cardList.remove(self.card)
                    
                card = {}
                card[config.plugins.CardConf.name.value] = {"name":config.plugins.CardConf.name.value}
                self.cardList.append(card)
                saveCards(self.cardList)
                self.session.open(MessageBox, _("The Satellite %s was saved successfully") % config.plugins.CardConf.name.value , MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)
                self.close()
            else:
                self.session.open(MessageBox, _("The Satellite already exist!"), MessageBox.TYPE_INFO, close_on_any_key=True, timeout=5)

    def checkCard(self, name):        
        sat = self.getCard(name)
        if sat is not None:
            if self.edit and self.old_card == name:
                return True
            else:
                return False
        return True
    
    def getCard(self, cardName):        
        for card in self.cardList :
            if card.get(cardName) is not None:
                return card 

class CardList(Screen):
        
    skin = """    
        <screen position="600,500" size="600,200"  title="Cards List" >
         <widget name="buttonred" position="10,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 
        <widget name="buttonblue" position="115,164" size="100,30" zPosition="5" valign="center" halign="center" backgroundColor="blue" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> 

            <widget transparent="1" name="menu" position="0,0" size="590,160" scrollbarMode="showOnDemand" />
        </screen>""" 
        
    def __init__(self, session, args=0):
        self.skin = SatelliteList.skin
        self.session = session
        Screen.__init__(self, session)
        self.menuList = []
        self.getMenuItens()
        self.menu = args
        self.onShow.append(self.updateMenu)
        self["menu"] = MenuList(self.menuList, enableWrapAround=True)
        self["buttonred"] = Label("Remove")
        self["buttonblue"] = Label("Add")
        self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions"],
                                    {
                                        "ok": self.go,
                                        "cancel": self.fechar,
                                        "back": self.fechar,
                                        "red": self.erase,
                                        "blue": self.add
                                    }, -1)
        
    
    def updateMenu(self):
        self.getMenuItens()
        self["menu"].setList(self.menuList)
                          
        
    def fechar(self):
        self["menu"].setList([])
        self.close()
    
    def go(self):
        returnValue = self["menu"].l.getCurrentSelection()[1]
        if returnValue is not None:  
            sat = self.getCard(returnValue)      
            self.session.open(CardScreenConf, sat, self.getCardList())

    def erase(self):
        self.session.openWithCallback(self.remove, MessageBox, _("Confirm removal?"), MessageBox.TYPE_YESNO)
        
    def remove(self, answer):
        if answer == True:
            returnValue = self["menu"].l.getCurrentSelection()[1]
            if returnValue is not None:
                card = self.getCard(returnValue)
                if card is not None:
                    cards = self.getCardList()
                    cards.remove(card)
                    saveCards(cards)
                    self.updateMenu()                  
    
    def add(self):
        returnValue = -1
        self.session.open(CardScreenConf, returnValue, self.getCardList())
    
    def getMenuItens(self):
        menuItens = []
        for card in self.getCardList():
            name = card[card.keys()[0]].get("name")           
            menuItens.append((_(name), name))

        self.menuList = menuItens
    
    def getCardList(self):
    
#        if not len(self.userList):
        cardList = []
        
        arq = open(twin2cc_cfg, "r")
        
        #Create temp file 
        
        for line in arq.readlines():
            
            #test if is not a comment
            if not line[0] == "#":     
                #is a F: ?" 
                if re.match("(\s+)??(CARD)\s+", line):
                    #split the line to get the values
                    info = re.split("\W+", line.strip())
                    
                    name = info[1]
                    #append the new card
                    card = {}
                    card[name] = {"name":name}
                    cardList.append(card)                    
                    
                    
        arq.close()
            
        return sorted(cardList)
        
    def getCard(self, cardName):        
        for card in self.getCardList():
            if card.get(cardName) is not None:
                return card  



def saveUsers(users=[]):
    from tempfile import mkstemp 
    from shutil import move 
    from os import remove, close 
    
    old_file = open(twin2cc_cfg, "r+")
    
    #Create temp file 
    fh, abs_path = mkstemp() 
    new_file = open(abs_path, 'w') 
    
    #remove all user entries from the configuration
    for line in old_file.readlines():
        new_line = line
        
        if not new_line[0] == "#":      
            if re.match("(\s+)??(F)(\s+)??\:", new_line):
                new_line = ""
      
          
        new_file.write(new_line)
    
    
    #add the news users
    #new_file.write("\n\n######### USERS TWINCONF ############\n")
    for user in users:
        name = user[user.keys()[0]].get("name")
        password = user[user.keys()[0]].get("password")   
        if name: 
            new_file.write("F: %s %s\n" % (name, password))
    
    
    #close temp file 
    new_file.close() 
    close(fh) 
    old_file.close() 
    #Remove original file 
    remove(twin2cc_cfg) 
    #Move new file 
    move(abs_path, twin2cc_cfg)  
    

def saveSats(satList=[]):
    from tempfile import mkstemp 
    from shutil import move 
    from os import remove, close 
    
    old_file = open(twin2cc_cfg, "r+")
    
    #Create temp file 
    fh, abs_path = mkstemp() 
    new_file = open(abs_path, 'w') 
    
    #remove all sat entries from the configuration
    for line in old_file.readlines():
        new_line = line
        
        if not new_line[0] == "#":      
            if re.match("(\s+)??(SAT)(\s+)??", new_line):
                new_line = ""
      
          
        new_file.write(new_line)
    
    
    #add the news users
    #new_file.write("\n\n######### SATS TWINCONF ############\n")
    for sat in satList:
        position = sat[sat.keys()[0]].get("position")
        name = sat[sat.keys()[0]].get("name")
        timeout = sat[sat.keys()[0]].get("timeout")  
        caid = sat[sat.keys()[0]].get("caid")
        pref = sat[sat.keys()[0]].get("pref")  
         
        if position == "W":
            name = hex((360 - int(name, 0)) * 10)[2:]
        else:
            name = hex(int(name, 0) * 10)[2:]
        
        if len(name) < 4:
            name = "0%s" % name         
        new_file.write("SAT %s:%s:%s:%s:%s\n" % (name, timeout, position,caid,pref))
    
    
    #close temp file 
    new_file.close() 
    close(fh) 
    old_file.close() 
    #Remove original file 
    remove(twin2cc_cfg) 
    #Move new file 
    move(abs_path, twin2cc_cfg) 
    

def saveCards(cardList=[]):
    from tempfile import mkstemp 
    from shutil import move 
    from os import remove, close 
    
    old_file = open(twin2cc_cfg, "r+")
    
    #Create temp file 
    fh, abs_path = mkstemp() 
    new_file = open(abs_path, 'w') 
    
    #remove all sat entries from the configuration
    for line in old_file.readlines():
        new_line = line
        
        if not new_line[0] == "#":      
            if re.match("(\s+)??(CARD)\s+", new_line):
                new_line = ""
      
          
        new_file.write(new_line)
    
    
    #add the news users
    #new_file.write("\n\n######### CARDS TWINCONF ############\n")
    for sat in cardList:
        name = sat[sat.keys()[0]].get("name")
              
        new_file.write("CARD %s:0000\n" % name)
    
    
    #close temp file 
    new_file.close() 
    close(fh) 
    old_file.close() 
    #Remove original file 
    remove(twin2cc_cfg) 
    #Move new file 
    move(abs_path, twin2cc_cfg)  
 

# Function main
def main(session, **kwargs):
    session.open(TwinScreen)


# Plugin descriptor, name, icon, etc.
def Plugins(**kwargs):
    return [
        PluginDescriptor(where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main, icon="plugin.png", name=twin2cc_title, description="Manage all the Twin2cc configurations"),
        PluginDescriptor(where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main, icon="plugin.png", name=twin2cc_title, description="Manage all the Twin2cc configurations")

      ]
